﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TableParsers;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Collections.ObjectModel;

namespace Speakup
{
    [Serializable]
    public class PersonalStats
    {
        public int Level { get; private set; }
        public int Unit { get; private set; }

        private AttendanceTable m_attendedClasses = new AttendanceTable();
        public ReadOnlyCollection<AttendanceTableEntry> AttendedClasses 
        { 
            get 
            {
                return m_attendedClasses.AsReadOnly();
            }
        }

        private CancelledTable m_cancelledClasses = new CancelledTable();
        public ReadOnlyCollection<CancelledTableEntry> CancelledClasses
        {
            get
            {
                return m_cancelledClasses.AsReadOnly();
            }        
        }


        private LevelResultsTable m_levelResults = new LevelResultsTable();
        public ReadOnlyCollection<LevelResultsEntry> LevelResults
        {
            get
            {
                return m_levelResults.AsReadOnly();
            }
        }

        private UnitResultsTable m_unitResults = new UnitResultsTable();
        public ReadOnlyCollection<UnitResultsEntry> UnitResults
        {
            get
            {
                return m_unitResults.AsReadOnly();
            }
        }
    

        public PersonalStats()
        {
            Level = 1;
            Unit = 1;
        }


        public static PersonalStats Fetch(WebLayer.LoginToken loginToken)
        {
            WebPageParser.WebPageCache pageCache = new WebPageParser.WebPageCache();
            pageCache.LoginToken = loginToken;

            return Fetch(pageCache);
        }

        public static PersonalStats Fetch(WebPageParser.WebPageCache pageCache)
        {
            PersonalStats stats = new PersonalStats();

            stats.m_attendedClasses = AttendanceTable.Fetch(pageCache);
            stats.m_cancelledClasses = CancelledTable.Fetch(pageCache);

            ResultsTable resultsTable = ResultsTable.Fetch(pageCache);

            stats.m_levelResults = LevelResultsTable.Create(resultsTable);
            stats.m_unitResults = UnitResultsTable.Create(resultsTable);

            LevelAndUnit levelAndUnit = LevelAndUnit.Fetch(pageCache);
            stats.Level = levelAndUnit.Level;
            stats.Unit = levelAndUnit.Unit;
            return stats;
        }

        public void Refresh(PersonalStats source)
        {
            this.m_attendedClasses = source.m_attendedClasses;
            this.m_cancelledClasses = source.m_cancelledClasses;
            this.m_levelResults = source.m_levelResults;
            this.m_unitResults = source.m_unitResults;
            this.Level = source.Level;
            this.Unit = source.Unit;

            OnRefresh();
        }

        [field: NonSerialized]
        public event EventHandler<EventArgs> Refreshed;

        protected void OnRefresh()
        {
            if (Refreshed != null)
            {
                Refreshed(this, new EventArgs());
            }
        }

        #region Persistency
        
        static readonly String DefaultFile = "PersonalStatsCache.bin";
        static public PersonalStats Load(String fileName)
        {
            IFormatter formatter = new BinaryFormatter();
            PersonalStats stats = null;
            using (FileStream s = File.OpenRead(fileName))
            {
                stats = (PersonalStats)formatter.Deserialize(s);
            }

            return stats;
        }
        static public PersonalStats Load()
        {
            return Load(DefaultFile);
        }
        
        public void Reload(String fileName)
        {            
            PersonalStats stats = PersonalStats.Load(fileName);
            Refresh(stats);
        }
        public void Reload()
        {       
            Reload(DefaultFile);
        }

        public void Save(String fileName)
        {
            IFormatter formatter = new BinaryFormatter();
            using (FileStream s = File.Create(fileName))
            {
                formatter.Serialize(s, this);
            }
        }
        public void Save()
        {
            Save(DefaultFile);
        }

        #endregion
    }
}
